package com.eastfair.venueservice.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eastfair.auth.api.UserAccountServiceFeign;
import com.eastfair.auth.dto.UserAccountDto;
import com.eastfair.auth.vo.UserAccountVo;
import com.eastfair.boot.request.PageParams;
import com.eastfair.core.base.entity.SuperEntity;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.exception.BizException;
import com.eastfair.core.utils.ConvertUtil;
import com.eastfair.venueservice.dao.ServiceCategoryMapper;
import com.eastfair.venueservice.dto.ServiceCategoryDTO;
import com.eastfair.venueservice.dto.ServiceCategoryPageQuery;
import com.eastfair.venueservice.entity.CreatCode;
import com.eastfair.venueservice.entity.ServiceCategory;
import com.eastfair.venueservice.entity.ServiceItem;
import com.eastfair.venueservice.enumeration.ServiceItemServiceStateEnum;
import com.eastfair.venueservice.exceptioncode.VenueServiceExceptionCode;
import com.eastfair.venueservice.service.ServiceAuditRecordService;
import com.eastfair.venueservice.service.ServiceCategoryService;
import com.eastfair.boot.service.SuperServiceImpl;

import com.eastfair.venueservice.service.ServiceItemService;
import com.eastfair.venueservice.vo.ServiceCategoryVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

//import com.baomidou.dynamic.datasource.annotation.DS;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 业务实现类
 * 服务分类
 * </p>
 *
 * @author lyw
 * @date 2022-07-13
 */
@Slf4j
@Service
//@DS("#thread.tenant")
public class ServiceCategoryServiceImpl extends SuperServiceImpl<ServiceCategoryMapper, ServiceCategory> implements ServiceCategoryService {

    public static final String SC = "SC";
    public static final String CATEGORY_CODE = "category_code";
    @Autowired
    private  ServiceCategoryMapper serviceCategoryMapper;
    @Autowired
    private ServiceAuditRecordService serviceAuditRecordService;
    @Autowired
    private ServiceItemService serviceItemService;
    @Autowired
    private UserAccountServiceFeign userAccountServiceFeign;



    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<ServiceCategory> modelList) {
        modelList.stream().forEach(s -> {
            s.setIsDeleted(BusinessConstant.YES);
        });
        // TODO: 2021/10/29 这里需要操作其他业务，如清空角色等
        return R.successDef();
    }

    @Override
    protected R<Boolean> handlerSave(ServiceCategory model) {
        model.setProjectId(ContextUtil.getProjectId());
        model.setSubsystemId(ContextUtil.getSubSystemId());
        model.setTenantId(ContextUtil.getTenantId());
        return R.successDef();
    }


    /**
     * 查询服务分类列表分页
     * @param params
     * @return
     */
    @Override
    public Page<ServiceCategoryVO> queryServiceCategoryList(PageParams<ServiceCategoryPageQuery> params) {
        log.info("ServiceCategoryServiceImpl +++++ queryServiceCategoryList - 查询服务分类列表 params={}", JSONObject.toJSON(params));
        Page<ServiceCategory> page = params.buildPage();
        ServiceCategoryPageQuery pageQuery = params.getModel();
        QueryWrapper<ServiceCategory> queryWrapper = new QueryWrapper<>();
        if(BusinessConstant.YES==pageQuery.getCategoryType()){
            List<Long> categoryIdList = serviceItemService.queryCategoryIds(pageQuery.getExhibitionManageId());
            categoryIdList.add(0L);
            //查询主场服务分类列表
            queryWrapper.lambda()
                    .like(Strings.isNotBlank(pageQuery.getServiceCategoryName()),ServiceCategory::getServiceCategoryName,pageQuery.getServiceCategoryName())
                    .eq(ServiceCategory::getIsDeleted,BusinessConstant.DELETE_NO)
                    .eq(Objects.nonNull(pageQuery.getId()),ServiceCategory::getId,pageQuery.getId())
                    .eq(Objects.nonNull(pageQuery.getCreatedBy()),ServiceCategory::getCreatedBy,pageQuery.getCreatedBy())
                    .eq(Objects.nonNull(pageQuery.getIsManage()),ServiceCategory::getIsManage,pageQuery.getIsManage())
                    .like(Strings.isNotBlank(pageQuery.getCategoryCode()),ServiceCategory::getCategoryCode,pageQuery.getCategoryCode())
                    .between(Objects.nonNull(pageQuery.getStartTime())
                                    && Objects.nonNull(pageQuery.getEndTime()),
                            ServiceCategory::getCreateTime, pageQuery.getStartTime(), pageQuery.getEndTime())
                    .and(e->e.or(f->f.eq(ServiceCategory::getExhibitionManageId,pageQuery.getExhibitionManageId()))
                            .or(f->f.in(SuperEntity::getId,categoryIdList)))
//                    .and(e->e.or(f->f.eq(ServiceCategory::getCategoryType,BusinessConstant.NO))
//                            .or(f->f.eq(ServiceCategory::getCategoryType,BusinessConstant.YES).eq(Objects.nonNull(pageQuery.getExhibitionManageId()),ServiceCategory::getExhibitionManageId,pageQuery.getExhibitionManageId())))
            .orderByDesc(ServiceCategory::getCreateTime);
            page = this.page(page, queryWrapper);
        }else {
            //查询综合服务分类列表
            queryWrapper.lambda()
                    .like(Strings.isNotBlank(pageQuery.getServiceCategoryName()),ServiceCategory::getServiceCategoryName,pageQuery.getServiceCategoryName())
                    .eq(ServiceCategory::getIsDeleted,BusinessConstant.DELETE_NO)
                    .eq(Objects.nonNull(pageQuery.getId()),ServiceCategory::getId,pageQuery.getId())
                    .eq(Objects.nonNull(pageQuery.getCreatedBy()),ServiceCategory::getCreatedBy,pageQuery.getCreatedBy())
                    .eq(ServiceCategory::getCategoryType,BusinessConstant.NO)
                    .like(Strings.isNotBlank(pageQuery.getCategoryCode()),ServiceCategory::getCategoryCode,pageQuery.getCategoryCode())
                    .between(Objects.nonNull(pageQuery.getStartTime())
                                    && Objects.nonNull(pageQuery.getEndTime()),
                            ServiceCategory::getCreateTime, pageQuery.getStartTime(), pageQuery.getEndTime())
                    .orderByDesc(ServiceCategory::getCreateTime);
            page = this.page(page, queryWrapper);
        }
        Page<ServiceCategoryVO> resultPage = ConvertUtil.convertPage(page, ServiceCategoryVO.class);
        if(Objects.isNull(resultPage.getRecords()) || resultPage.getRecords().size()==0){
            return resultPage;
        }
        List<Long> userIds = resultPage.getRecords().stream().map(ServiceCategoryVO::getCreatedBy).collect(Collectors.toList());
        UserAccountDto userAccountDto = new UserAccountDto();
        userAccountDto.setUserIds(userIds);
        //获取人员信息
        R<List<UserAccountVo>> listR = userAccountServiceFeign.querySimpleByIds(userAccountDto);
        //把人员信息转成map
        if(Objects.nonNull(listR) && CollectionUtils.isNotEmpty(listR.getData())){
            Map<Long, UserAccountVo> userMap = listR.getData().stream().collect(Collectors.toMap(UserAccountVo::getId, Function.identity()));
            //获取分类下服务项数量
            if (Objects.nonNull(resultPage.getRecords()) && resultPage.getRecords().size()>0) {
                resultPage.getRecords().forEach((s)->{
                    Integer sum = serviceItemService.getServiceItemSumByCategoryId(s.getId(),pageQuery.getServiceProviderId());
                    s.setServiceItemSum(sum);
                    try{
                        s.setCreateName(userMap.get(s.getCreatedBy()).getRealName());
                    }catch (Exception e){
                        log.warn(s.getCreatedBy()+"未查询到用户信息");
                    }
                });
            }
        }
        return resultPage;
    }

    /**
     * 查询服务分类列表
     * @param categoryType,exhibitionManageId
     * @return
     */
    @Override
    public List<ServiceCategoryVO> getCategoryListByExhibitionManageId(Integer categoryType,Long exhibitionManageId) {
        List<ServiceCategory> list=Lists.newArrayList();
        //判断是否是综合服务查询或者主场查询
        if(BusinessConstant.NO==categoryType){
            //查询服务分类列表
            QueryWrapper<ServiceCategory> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .eq(ServiceCategory::getIsDeleted,BusinessConstant.DELETE_NO)
                    .eq(ServiceCategory::getCategoryType,categoryType);
            list = this.list(queryWrapper);
        }else {
            //查询服务分类列表
            QueryWrapper<ServiceCategory> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .eq(ServiceCategory::getIsDeleted,BusinessConstant.DELETE_NO)
                    .and(e->e.or(f->f.eq(ServiceCategory::getCategoryType,BusinessConstant.NO))
                            .or(f->f.eq(ServiceCategory::getCategoryType,BusinessConstant.YES).eq(Objects.nonNull(exhibitionManageId),ServiceCategory::getExhibitionManageId,exhibitionManageId)));
            list = this.list(queryWrapper);
        }
        List<ServiceCategoryVO> serviceCategoryVOList = ConvertUtil.convertList(list, ServiceCategoryVO.class);
        return serviceCategoryVOList;
    }
    /**
     * 查询服务分类列表
     * @param categoryType
     * @return
     */
    @Override
    public List<ServiceCategoryVO> getCategoryList(Integer categoryType) {
        List<ServiceCategory> list=Lists.newArrayList();
        //判断是否是综合服务查询或者主场查询
        if(BusinessConstant.NO==categoryType){
            //查询服务分类列表
            QueryWrapper<ServiceCategory> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .eq(ServiceCategory::getIsDeleted,BusinessConstant.DELETE_NO)
                    .eq(ServiceCategory::getCategoryType,categoryType);
            list = this.list(queryWrapper);
        }else {
            //查询服务分类列表
            QueryWrapper<ServiceCategory> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .eq(ServiceCategory::getIsDeleted,BusinessConstant.DELETE_NO)
                    .and(e->e.or(f->f.eq(ServiceCategory::getCategoryType,BusinessConstant.NO))
                            .or(f->f.eq(ServiceCategory::getCategoryType,BusinessConstant.YES)));
            list = this.list(queryWrapper);
        }
        List<ServiceCategoryVO> serviceCategoryVOList = ConvertUtil.convertList(list, ServiceCategoryVO.class);
        return serviceCategoryVOList;
    }

    /**
     * 保存服务分类
     * @param serviceCategoryDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveServiceCategoryInfo(ServiceCategoryDTO serviceCategoryDTO) {
        log.info("ServiceCategoryServiceImpl +++++ saveServiceCategoryInfo - 保存服务分类 params={}", JSONObject.toJSON(serviceCategoryDTO));
        List<ServiceCategory> list= this.list(new QueryWrapper<ServiceCategory>().lambda()
                .eq(ServiceCategory::getIsDeleted, BusinessConstant.DELETE_NO)
                .eq(ServiceCategory::getCategoryType,BusinessConstant.NO)
                .eq(Strings.isNotBlank(serviceCategoryDTO.getServiceCategoryName()), ServiceCategory::getServiceCategoryName, serviceCategoryDTO.getServiceCategoryName()));
        //服务分类名称查重
        if (Objects.nonNull(list) && list.size() > 0) {
            throw BizException.wrap(VenueServiceExceptionCode.SERVICE_CATEGORY_EXISTENCE);
        }
        String code = CreatCode.creatCode(serviceCategoryMapper, CATEGORY_CODE,5, SC);
        serviceCategoryDTO.setCategoryCode(code);
        ServiceCategory serviceCategory = BeanUtil.toBean(serviceCategoryDTO, ServiceCategory.class);
        return this.save(serviceCategory);
    }

    /**
     * 修改服务分类
     * @param serviceCategoryDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateServiceCategoryById(ServiceCategoryDTO serviceCategoryDTO) {
        log.info("ServiceCategoryServiceImpl +++++ updateServiceCategoryById - 修改服务分类 params={}", JSONObject.toJSON(serviceCategoryDTO));

        List<ServiceCategory> list= this.list(new QueryWrapper<ServiceCategory>().lambda()
                .eq(ServiceCategory::getIsDeleted, BusinessConstant.DELETE_NO)
                .eq(ServiceCategory::getCategoryType,BusinessConstant.NO)
                .eq(Strings.isNotBlank(serviceCategoryDTO.getServiceCategoryName()), ServiceCategory::getServiceCategoryName, serviceCategoryDTO.getServiceCategoryName()));
        //展厅分类名称查重
        //判断是否是自己
        if (Objects.nonNull(list) && list.size()>0 && Objects.nonNull(list.get(0)) && list.get(0).getId().longValue()!=serviceCategoryDTO.getId().longValue()) {
            throw BizException.wrap(VenueServiceExceptionCode.SERVICE_CATEGORY_EXISTENCE);
        }
      //  Integer sum = serviceItemService.getServiceItemSumByCategoryId(serviceCategoryDTO.getId());

        ServiceCategory serviceCategory = BeanUtil.toBean(serviceCategoryDTO, ServiceCategory.class);
        return this.updateById(serviceCategory);
    }

    /**
     * 删除服务分类
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delServiceCategoryById(Long id) {
        log.info("ServiceCategoryServiceImpl +++++ delServiceCategoryById - 删除服务分类 params={}", JSONObject.toJSON(id));
        ServiceCategory serviceCategory = ServiceCategory.builder()
                .id(id)
                .isDeleted(BusinessConstant.YES)
                .build();
        // 校验是否存在已上架的服务
        int count = serviceItemService.count(new QueryWrapper<ServiceItem>().lambda().eq(ServiceItem::getIsDeleted, BusinessConstant.NO)
                .eq(ServiceItem::getServiceCategoryId, id)
                .eq(ServiceItem::getServiceState, ServiceItemServiceStateEnum.ON_SHELVES));
        if(count>0){
            throw BizException.wrap(VenueServiceExceptionCode.SERVICES_CATEGORY_CANT_DELETE);
        }
        return this.updateById(serviceCategory);
    }

    @Override
    public List<ServiceCategoryVO> getCategoryListByIds(List<Long> ids) {
        if(CollectionUtils.isNotEmpty(ids)){
            List<ServiceCategory> serviceCategories = listByIds(ids);
            return ConvertUtil.convertList(serviceCategories, ServiceCategoryVO.class);
        }else {
            return new ArrayList<>();
        }
    }
}
